﻿// /*!
//  * Project: Salient.Web.HttpLib
//  * http://salient.codeplex.com
//  *
//  * Copyright 2010, Sky Sanders
//  * Dual licensed under the MIT or GPL Version 2 licenses.
//  * http://salient.codeplex.com/license
//  *
//  * Date: April 11 2010 
//  */
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace Salient.Web
{
    /// <summary>
    /// Utility class to facilitate mapping ContentType enum to corresponding constants
    /// </summary>
    public static class ContentTypes
    {
        ///<summary>
        ///</summary>
        public const string ApplicationForm = "application/x-www-form-urlencoded; charset=UTF-8";
        ///<summary>
        ///</summary>
        public const string ApplicationJson = "application/json; charset=UTF-8";
        ///<summary>
        ///</summary>
        public const string None = "";
        ///<summary>
        ///</summary>
        public const string TextJson = "text/json; charset=UTF-8";

        ///<summary>
        ///</summary>
        ///<param name="value"></param>
        ///<returns></returns>
        public static string AsString(this ContentType value)
        {
            switch (value)
            {
                case ContentType.None:
                    return None;
                case ContentType.ApplicationJson:
                    return ApplicationJson;
                case ContentType.TextJson:
                    return TextJson;
                case ContentType.ApplicationForm:
                    return ApplicationForm;
                default:
                    return None;
            }
        }

        /// <summary>
        /// TODO: try to use this instead of registry
        /// </summary>
        /// <param name="pBC"></param>
        /// <param name="pwzUrl"></param>
        /// <param name="pBuffer"></param>
        /// <param name="cbSize"></param>
        /// <param name="pwzMimeProposed"></param>
        /// <param name="dwMimeFlags"></param>
        /// <param name="ppwzMimeOut"></param>
        /// <param name="dwReserved"></param>
        /// <returns></returns>
        [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
        static extern int FindMimeFromData(IntPtr pBC,[MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 3)] byte[] pBuffer,int cbSize,[MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed,int dwMimeFlags,out IntPtr ppwzMimeOut,int dwReserved);

        /// <summary>
        /// Attempts to query registry for content-type of suppied file name.
        /// </summary>
        public static bool TryGetContentType(string fileName, out string contentType)
        {
            try
            {
                RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"MIME\Database\Content Type");

                if (key != null)
                {
                    foreach (string keyName in key.GetSubKeyNames())
                    {
                        RegistryKey subKey = key.OpenSubKey(keyName);
                        if (subKey != null)
                        {
                            string subKeyValue = (string)subKey.GetValue("Extension");

                            if (!string.IsNullOrEmpty(subKeyValue))
                            {
                                if (string.Compare(Path.GetExtension(fileName).ToUpperInvariant(),
                                                   subKeyValue.ToUpperInvariant(), StringComparison.OrdinalIgnoreCase) ==
                                    0)
                                {
                                    contentType = keyName;
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            // ReSharper disable EmptyGeneralCatchClause
            catch
            {
                // fail silently
                // TODO: rethrow registry access denied errors
            }
            // ReSharper restore EmptyGeneralCatchClause
            contentType = "";
            return false;
        }
    }
}